package com.yangtu.nearbyshop.wx.service;

import com.alibaba.druid.support.json.JSONUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.pagehelper.PageInfo;
import com.yangtu.nearbyshop.core.corg.CorgChannel;
import com.yangtu.nearbyshop.core.express.ExpressService;
import com.yangtu.nearbyshop.core.express.dao.ExpressInfo;
import com.yangtu.nearbyshop.core.notify.NotifyService;
import com.yangtu.nearbyshop.core.notify.NotifyType;
import com.yangtu.nearbyshop.core.qcode.QCodeService;
import com.yangtu.nearbyshop.core.system.SystemConfig;
import com.yangtu.nearbyshop.core.util.*;
import com.yangtu.nearbyshop.db.domain.*;
import com.yangtu.nearbyshop.db.service.*;
import com.yangtu.nearbyshop.db.service.itf.INearbyshopMercRebateService;
import com.yangtu.nearbyshop.db.service.itf.INearbyshopOrderRefundService;
import com.yangtu.nearbyshop.db.service.itf.INearbyshopOrderService;
import com.yangtu.nearbyshop.db.util.CouponUserConstant;
import com.yangtu.nearbyshop.db.util.OrderHandleOption;
import com.yangtu.nearbyshop.db.util.OrderUtil;
import com.yangtu.nearbyshop.db.vo.OrderInfoVo;
import com.yangtu.nearbyshop.wx.util.BeanUtil;
import com.yangtu.nearbyshop.wx.util.WeChatBuyPost;
import com.yangtu.nearbyshop.wx.util.WxResponseCode;
import com.yangtu.nearbyshop.wx.util.XmlHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

import static com.yangtu.nearbyshop.core.corg.Const.*;
import static com.yangtu.nearbyshop.core.corg.Const.UP_CORG_TRAN_ID;

/**
 * 订单服务
 *
 * <p>
 * 订单状态：
 * 101 订单生成，未支付；102，下单后未支付用户取消；103，下单后未支付超时系统自动取消
 * 201 支付完成，商家未发货；202，订单生产，已付款未发货，但是退款取消；
 * 301 商家发货，用户未确认；
 * 401 用户确认收货； 402 用户没有确认收货超过一定时间，系统自动确认收货；
 *
 * <p>
 * 用户操作：
 * 当101用户未付款时，此时用户可以进行的操作是取消订单，或者付款操作
 * 当201支付完成而商家未发货时，此时用户可以取消订单并申请退款
 * 当301商家已发货时，此时用户可以有确认收货的操作
 * 当401用户确认收货以后，此时用户可以进行的操作是删除订单，评价商品，或者再次购买
 * 当402系统自动确认收货以后，此时用户可以删除订单，评价商品，或者再次购买
 *
 * <p>
 * 注意：目前不支持订单退货和售后服务
 */
@Service
public class WxOrderService {
    private final Log logger = LogFactory.getLog(WxOrderService.class);

    @Autowired
    private NearbyshopUserService userService;
    @Autowired
    private NearbyshopOrderService orderService;
    @Autowired
    private NearbyshopOrderGoodsService orderGoodsService;
    @Autowired
    private NearbyshopAddressService addressService;
    @Autowired
    private NearbyshopCartService cartService;
    @Autowired
    private NearbyshopRegionService regionService;
    @Autowired
    private NearbyshopGoodsProductService productService;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private NotifyService notifyService;
    @Autowired
    private NearbyshopUserFormIdService formIdService;
    @Autowired
    private NearbyshopGrouponRulesService grouponRulesService;
    @Autowired
    private NearbyshopGrouponService grouponService;
    @Autowired
    private QCodeService qCodeService;
    @Autowired
    private ExpressService expressService;
    @Autowired
    private NearbyshopCommentService commentService;
    @Autowired
    private NearbyshopCouponService couponService;
    @Autowired
    private NearbyshopCouponUserService couponUserService;
    @Autowired
    private CouponVerifyService couponVerifyService;
    @Autowired
    private NearbyshopGoodsService goodsService;

    @Autowired
    private CorgChannel cnlPayService;

    @Autowired
    private NearbyshopMercService mercService;

    @Autowired
    private INearbyshopOrderRefundService refundService;

    @Autowired
    private INearbyshopOrderService orderService2;

    @Autowired
    private INearbyshopMercRebateService rebateService;

    @Autowired
    private NearbyshopAdminService adminService;

    private String detailedAddress(NearbyshopAddress nearbyshopAddress) {
        Integer provinceId = nearbyshopAddress.getProvinceId();
        Integer cityId = nearbyshopAddress.getCityId();
        Integer areaId = nearbyshopAddress.getAreaId();
        String provinceName = regionService.findById(provinceId).getName();
        String cityName = regionService.findById(cityId).getName();
        String areaName = regionService.findById(areaId).getName();
        String fullRegion = provinceName + " " + cityName + " " + areaName;
        return fullRegion + " " + nearbyshopAddress.getAddress();
    }

    /**
     * 订单列表
     *
     * @param userId   用户ID
     * @param showType 订单信息：
     *                 0，全部订单；
     *                 1，待付款；
     *                 2，待发货；
     *                 3，待收货；
     *                 4，待评价。
     * @param page     分页页数
     * @param size     分页大小
     * @return 订单列表
     */
    public Object list(Integer userId, Integer showType, Integer page, Integer size) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        List<Short> orderStatus = OrderUtil.orderStatus(showType);
        List<NearbyshopOrder> orderList = orderService.queryByOrderStatus(userId, orderStatus, page, size);
        long count = PageInfo.of(orderList).getTotal();
        int totalPages = (int) Math.ceil((double) count / size);

        List<Map<String, Object>> orderVoList = new ArrayList<>(orderList.size());
        for (NearbyshopOrder order : orderList) {
            Map<String, Object> orderVo = new HashMap<>();
            orderVo.put("id", order.getId());
            orderVo.put("orderSn", order.getOrderSn());
            orderVo.put("actualPrice", order.getActualPrice());
            orderVo.put("freightPrice", order.getFreightPrice());
            orderVo.put("youhuiPrice", order.getYouhuiPrice());
            orderVo.put("buchaPrice", order.getBuchaPrice());
            orderVo.put("orderStatusText", OrderUtil.orderStatusText(order));
            orderVo.put("handleOption", OrderUtil.build(order));

            NearbyshopGroupon groupon = grouponService.queryByOrderId(order.getId());
            if (groupon != null) {
                orderVo.put("isGroupin", true);
            } else {
                orderVo.put("isGroupin", false);
            }

            List<NearbyshopOrderGoods> orderGoodsList = new ArrayList<>();
            if(order.getAdminId() == null){
                String[] ids = order.getCorgOrderSn().split(",");
                for(String oid : ids){
                    orderGoodsList.addAll(orderGoodsService.queryByOid(Integer.valueOf(oid)));
                }
            }else {
                orderGoodsList = orderGoodsService.queryByOid(order.getId());
            }

            List<Map<String, Object>> orderGoodsVoList = new ArrayList<>(orderGoodsList.size());
            for (NearbyshopOrderGoods orderGoods : orderGoodsList) {
                Map<String, Object> orderGoodsVo = new HashMap<>();
                orderGoodsVo.put("id", orderGoods.getId());
                orderGoodsVo.put("goodsName", orderGoods.getGoodsName());
                orderGoodsVo.put("number", orderGoods.getNumber());
                orderGoodsVo.put("picUrl", orderGoods.getPicUrl());
                orderGoodsVoList.add(orderGoodsVo);
            }
            orderVo.put("goodsList", orderGoodsVoList);

            orderVoList.add(orderVo);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("count", count);
        result.put("data", orderVoList);
        result.put("totalPages", totalPages);

        return ResponseUtil.ok(result);
    }

    /**
     * 订单详情
     *
     * @param userId  用户ID
     * @param orderId 订单ID
     * @return 订单详情
     */
    public Object detail(Integer userId, Integer orderId) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        // 订单信息
        NearbyshopOrder order = orderService.findById(orderId);

        if (null == order) {
            return ResponseUtil.fail(WxResponseCode.ORDER_UNKNOWN, "订单不存在");
        }
        if (!order.getUserId().equals(userId)) {
            return ResponseUtil.fail(WxResponseCode.ORDER_INVALID, "不是当前用户的订单");
        }
        Map<String, Object> orderVo = new HashMap<String, Object>();
        orderVo.put("id", order.getId());
        orderVo.put("orderSn", order.getOrderSn());
        orderVo.put("addTime", order.getAddTime());
        orderVo.put("consignee", order.getConsignee());
        orderVo.put("mobile", order.getMobile());
        orderVo.put("address", order.getAddress());
        orderVo.put("goodsPrice", order.getGoodsPrice());
        orderVo.put("freightPrice", order.getFreightPrice());
        orderVo.put("actualPrice", order.getActualPrice());
        orderVo.put("orderStatusText", OrderUtil.orderStatusText(order));
        orderVo.put("handleOption", OrderUtil.build(order));
        orderVo.put("expCode", order.getShipChannel());
        orderVo.put("expNo", order.getShipSn());
        orderVo.put("message", order.getMessage());
        orderVo.put("youhuiPrice", order.getYouhuiPrice());
        orderVo.put("buchaPrice", order.getBuchaPrice());

        List<NearbyshopOrderGoods> orderGoodsList = new ArrayList<>();
        if(null == order.getAdminId()){
            String[] ids = order.getCorgOrderSn().split(",");
            for(String oid : ids){
                orderGoodsList.addAll(orderGoodsService.queryByOid(Integer.valueOf(oid)));
            }
        }else {
            orderGoodsList = orderGoodsService.queryByOid(order.getId());
        }

        Map<String, Object> result = new HashMap<>();
        result.put("orderInfo", orderVo);
        result.put("orderGoods", orderGoodsList);

        // 订单状态为已发货且物流信息不为空
        //"YTO", "800669400640887922"
        if (order.getOrderStatus().equals(OrderUtil.STATUS_SHIP)) {
            String code = expressService.getVendorCode(order.getShipChannel());
            ExpressInfo ei = expressService.getExpressInfo(code, order.getShipSn());
            result.put("expressInfo", ei);
        }

/*        NearbyshopMerc merc = mercService.queryByMercNo(order.getMercNo());
        orderVo.put("mercNo",merc.getMercNo());
        orderVo.put("mercName",merc.getMercName());
        orderVo.put("mercAddr",merc.getMercAddr());
        orderVo.put("mercMobile",merc.getMobile());*/
        return ResponseUtil.ok(result);

    }

    /**
     * 提交订单
     * <p>
     * 1. 创建订单表项和订单商品表项;
     * 2. 购物车清空;
     * 3. 优惠券设置已用;
     * 4. 商品货品库存减少;
     * 5. 如果是团购商品，则创建团购活动表项。
     *
     * @param userId 用户ID
     * @param body   订单信息，{ cartId：xxx, addressId: xxx, couponId: xxx, message: xxx, grouponRulesId: xxx,  grouponLinkId: xxx }
     * @return 提交订单操作结果
     */
    @Transactional
    public Object submit(Integer userId, String body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        NearbyshopUser user = userService.findById(userId);

        if (body == null) {
            return ResponseUtil.badArgument();
        }
        Integer cartId = JacksonUtil.parseInteger(body, "cartId");
        Integer couponId = JacksonUtil.parseInteger(body, "couponId");
        String message = JacksonUtil.parseString(body, "message");
        Integer grouponRulesId = JacksonUtil.parseInteger(body, "grouponRulesId");
        Integer grouponLinkId = JacksonUtil.parseInteger(body, "grouponLinkId");
        String consignee = JacksonUtil.parseString(body, "consignee");
        String mobile = JacksonUtil.parseString(body, "mobile");
        String detailedAddress = JacksonUtil.parseString(body, "address");
//        String mercNo = JacksonUtil.parseString(body, "mercNo");

        String longitude = JacksonUtil.parseString(body, "longitude");
        String latitude = JacksonUtil.parseString(body, "latitude");

        if(StringUtils.isEmpty(longitude) || StringUtils.isEmpty(latitude) ){
            return ResponseUtil.fail("经纬度不能为空");
        }

        String mercNo = user.getMercNo();

        //如果是团购项目,验证活动是否有效
        if (grouponRulesId != null && grouponRulesId > 0) {
            NearbyshopGrouponRules rules = grouponRulesService.queryById(grouponRulesId);
            //找不到记录
            if (rules == null) {
                return ResponseUtil.badArgument();
            }
            //团购活动已经过期
            if (grouponRulesService.isExpired(rules)) {
                return ResponseUtil.fail(WxResponseCode.GROUPON_EXPIRED, "团购活动已过期!");
            }
        }

        if (cartId == null || couponId == null || mobile == null) {
            return ResponseUtil.badArgument();
        }

        // 收货地址
//        NearbyshopAddress checkedAddress = addressService.findById(addressId);
//        if (checkedAddress == null) {
//            return ResponseUtil.badArgument();
//        }

        // 团购优惠
        BigDecimal grouponPrice = new BigDecimal(0.00);
        NearbyshopGrouponRules grouponRules = grouponRulesService.queryById(grouponRulesId);
        if (grouponRules != null) {
            grouponPrice = grouponRules.getDiscount();
        }

        // 货品价格
        List<NearbyshopCart> checkedGoodsList = null;
        if (cartId.equals(0)) {
            checkedGoodsList = cartService.queryByUidAndChecked(userId);
        } else {
            NearbyshopCart cart = cartService.findById(cartId);
            checkedGoodsList = new ArrayList<>(1);
            checkedGoodsList.add(cart);
        }
        if (checkedGoodsList.size() == 0) {
            return ResponseUtil.badArgumentValue();
        }
//        BigDecimal checkedGoodsPrice = new BigDecimal(0.00);
        Map<Integer,OrderInfoVo> subOrders = new HashMap<>();
        for (NearbyshopCart checkGoods : checkedGoodsList) {
            OrderInfoVo orderInfoVo = null;
            //判断用户是否已超出限购数量
            //还可以购买的数量
            NearbyshopGoods goods = goodsService.findById(checkGoods.getGoodsId());
            if(goods.getSaleLimit()>=0){
                Integer count = goods.getSaleLimit() - orderGoodsService.countByGoodsId(userId,goods.getId());
                if (checkGoods.getNumber() > count) {
                    return ResponseUtil.fail(WxResponseCode.GOODS_UNSHELVE,
                            "有限购品！");
                }
            }

            if(!subOrders.containsKey(goods.getBrandId())){
                orderInfoVo = new OrderInfoVo();
                orderInfoVo.setAdminId(goods.getBrandId());
                orderInfoVo.setCheckedGoodsPrice(new BigDecimal(0.00));
                orderInfoVo.setCouponPrice(new BigDecimal(0.00));
                orderInfoVo.setGrouponPrice(new BigDecimal(0.00));
                subOrders.put(goods.getBrandId(),orderInfoVo);
            }else {
                orderInfoVo = subOrders.get(goods.getBrandId());
            }

            //  只有当团购规格商品ID符合才进行团购优惠
            if (grouponRules != null && grouponRules.getGoodsId().equals(checkGoods.getGoodsId())) {
                orderInfoVo.setCheckedGoodsPrice(orderInfoVo.getCheckedGoodsPrice()
                        .add(checkGoods.getPrice().subtract(grouponPrice)
                                .multiply(new BigDecimal(checkGoods.getNumber()))));
                orderInfoVo.setGrouponPrice(grouponPrice);
            } else {
                orderInfoVo.setCheckedGoodsPrice(orderInfoVo.getCheckedGoodsPrice()
                        .add(checkGoods.getPrice().multiply(new BigDecimal(checkGoods.getNumber()))));
            }

        }
        //找到费用最高的
        Iterator iter = subOrders.keySet().iterator();
        OrderInfoVo orderInfoVo = null;
        BigDecimal minPrice = new BigDecimal(0.00);
        while (iter.hasNext()) {
            OrderInfoVo infoVo = subOrders.get((Integer)iter.next());
            if(infoVo.getCheckedGoodsPrice().compareTo(minPrice) == 1){
                orderInfoVo = infoVo;
            }
        }
        // 获取可用的优惠券信息
        // 使用优惠券减免的金额
        //BigDecimal couponPrice = new BigDecimal(0.00);
        // 如果couponId=0则没有优惠券，couponId=-1则不使用优惠券
        if (couponId != 0 && couponId != -1) {
            NearbyshopCoupon coupon = couponVerifyService.checkCoupon(userId, couponId, orderInfoVo.getCheckedGoodsPrice());
            if (coupon == null) {
                return ResponseUtil.badArgumentValue();
            }
            orderInfoVo.setCouponPrice(coupon.getDiscount());
        }

        // 根据订单商品总价计算运费，满足条件（例如88元）则免运费，否则需要支付运费（例如8元）；
        BigDecimal freightPrice = new BigDecimal(0.00);
//        if (checkedGoodsPrice.compareTo(SystemConfig.getFreightLimit()) < 0) {
//            freightPrice = SystemConfig.getFreight();
//        }

        // 可以使用的其他钱，例如用户积分
        BigDecimal integralPrice = new BigDecimal(0.00);

        // 订单费用
        //BigDecimal orderTotalPrice = checkedGoodsPrice.add(freightPrice).subtract(couponPrice);
        // 最终支付费用
        //BigDecimal actualPrice = orderTotalPrice.subtract(integralPrice);

        //Integer orderId = null;
        Integer couponOrderId = null;
        Integer groupOrderId = null;
        NearbyshopOrder order = null;
        // 订单
        Iterator iter2 = subOrders.keySet().iterator();
        String orderIds = "";
        BigDecimal totalActPrice = new BigDecimal(0.00);
        BigDecimal totalGoodsPrice = new BigDecimal(0.00);
        BigDecimal totalFreightPrice = new BigDecimal(0.00);
        BigDecimal totalCouponPrice = new BigDecimal(0.00);
        BigDecimal totalIntegralPrice = new BigDecimal(0.00);
        BigDecimal totalOrderPrice = new BigDecimal(0.00);
        BigDecimal totalGrouponPrice = new BigDecimal(0.00);
        BigDecimal totalYouhuiPrice = new BigDecimal(0.00);
        BigDecimal totalBuchaPrice = new BigDecimal(0.00);
        String comOrderSn = orderService.generateOrderSn(userId);
        while (iter2.hasNext()){
            OrderInfoVo infoVo = subOrders.get((Integer)iter2.next());
            order = new NearbyshopOrder();
            order.setUserId(userId);
            order.setAdminId(infoVo.getAdminId());
            order.setCorgOrderSn("test");
            order.setMercNo(mercNo);
            order.setOrderSn(orderService.generateOrderSn(userId));
            order.setPayOrderSn(comOrderSn);
            order.setOrderStatus(OrderUtil.STATUS_CREATE);
//        order.setConsignee(checkedAddress.getName());
//        order.setMobile(checkedAddress.getMobile());
            order.setConsignee(consignee);
            order.setMobile(mobile);
            order.setMessage(message);
//        String detailedAddress = detailedAddress(checkedAddress);
//            String detailedAddress ="";
            order.setAddress(detailedAddress);
            order.setGoodsPrice(infoVo.getCheckedGoodsPrice());
            order.setFreightPrice(freightPrice);
            order.setCouponPrice(infoVo.getCouponPrice());
            order.setIntegralPrice(integralPrice);
            BigDecimal orderTotalPrice = infoVo.getCheckedGoodsPrice().add(freightPrice).subtract(infoVo.getCouponPrice());
            order.setOrderPrice(orderTotalPrice);
            BigDecimal actualPrice = orderTotalPrice.subtract(integralPrice);
            order.setActualPrice(actualPrice);
            order.setYouhuiPrice(new BigDecimal("0"));
            order.setBuchaPrice(new BigDecimal("0"));
            order.setDeleted(true);
            // 有团购活动
            if (grouponRules != null) {
                order.setGrouponPrice(infoVo.getGrouponPrice());    //  团购价格
            } else {
                order.setGrouponPrice(new BigDecimal(0.00));    //  团购价格
            }
            totalGrouponPrice = totalGrouponPrice.add(order.getGrouponPrice());
            // 添加订单表项
            orderService.add(order);
            if(infoVo.getCouponPrice().compareTo(new BigDecimal(0.00))  != 0 ){
                couponOrderId = order.getId();
            }

            if(infoVo.getGrouponPrice().compareTo(new BigDecimal(0.00))  != 0 ){
                groupOrderId = order.getId();
            }

            // 添加订单商品表项
            BigDecimal maxYunfei = new BigDecimal(0.00);
            BigDecimal zongYunfei = new BigDecimal(0.00);
            int totalNum = 0;
            for (NearbyshopCart cartGoods : checkedGoodsList) {
                NearbyshopGoods goods = goodsService.findById(cartGoods.getGoodsId());
                if(goods.getBrandId().equals(infoVo.getAdminId())){
                    // 订单商品
                    NearbyshopOrderGoods orderGoods = new NearbyshopOrderGoods();
                    orderGoods.setOrderId(order.getId());
                    orderGoods.setGoodsId(cartGoods.getGoodsId());
                    orderGoods.setGoodsSn(cartGoods.getGoodsSn());
                    orderGoods.setProductId(cartGoods.getProductId());

                    NearbyshopGoodsProduct goodsProduct = productService.findById(cartGoods.getProductId());
                    if(goodsProduct.getFreightPrice().compareTo(maxYunfei)  > 0 ){
                        maxYunfei = goodsProduct.getFreightPrice();
                    }

                    orderGoods.setGoodsName(cartGoods.getGoodsName());
                    orderGoods.setPicUrl(cartGoods.getPicUrl());
                    orderGoods.setPrice(cartGoods.getPrice());
                    orderGoods.setNumber(cartGoods.getNumber());
                    orderGoods.setSpecifications(cartGoods.getSpecifications());
                    orderGoods.setAddTime(LocalDateTime.now());
                    orderGoods.setMercProfit(cartGoods.getMercProfit());
                    orderGoods.setMercNo(mercNo);
                    orderGoodsService.add(orderGoods);
                    totalNum=totalNum+cartGoods.getNumber();
                    zongYunfei = zongYunfei.add(goodsProduct.getFreightPrice().multiply(new BigDecimal(cartGoods.getNumber())));
                }
            }

            NearbyshopAdmin orderAdmin = adminService.findById(order.getAdminId());

            BigDecimal youhui = zongYunfei.subtract(maxYunfei).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().negate();
            logger.info("youhui=" + youhui);
            BigDecimal bucha = GeoUtils.calcBucha(Double.valueOf(latitude),Double.valueOf(longitude),
                    Double.valueOf(orderAdmin.getLatitude()),Double.valueOf(orderAdmin.getLongitude()));
            logger.info("bucha=" + bucha);
            NearbyshopOrder orderUpdate = orderService.findById(order.getId());
            orderUpdate.setId(order.getId());
            orderUpdate.setYouhuiPrice(youhui);
            orderUpdate.setBuchaPrice(bucha);
            //重新计算运费
            orderUpdate.setFreightPrice(bucha.add(youhui).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros());
            //重新设置实际支付金额
            orderUpdate.setActualPrice(order.getActualPrice().add(orderUpdate.getFreightPrice()).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros());
            orderService.updateWithOptimisticLocker(orderUpdate);

            totalFreightPrice = totalFreightPrice.add(orderUpdate.getFreightPrice());
            totalYouhuiPrice = totalYouhuiPrice.add(youhui);
            totalBuchaPrice = totalBuchaPrice.add(bucha);

            totalActPrice = totalActPrice.add(orderUpdate.getActualPrice());
            totalCouponPrice = totalCouponPrice.add(order.getCouponPrice());

            totalGoodsPrice = totalGoodsPrice.add(order.getGoodsPrice());
            totalIntegralPrice = totalIntegralPrice.add(order.getIntegralPrice());
            totalOrderPrice = totalOrderPrice.add(order.getOrderPrice());
            orderIds += order.getId()+",";
        }

        // 删除购物车里面的商品信息
        cartService.clearGoods(userId);

        // 商品货品数量减少
        for (NearbyshopCart checkGoods : checkedGoodsList) {
            Integer productId = checkGoods.getProductId();
            NearbyshopGoodsProduct product = productService.findById(productId);

            Integer remainNumber = product.getNumber() - checkGoods.getNumber();
            if (remainNumber < 0) {
                throw new RuntimeException("下单的商品货品数量大于库存量");
            }
            if (productService.reduceStock(productId, checkGoods.getNumber()) == 0) {
                throw new RuntimeException("商品货品库存减少失败");
            }

/*            NearbyshopGoods goods = goodsService.findById(checkGoods.getGoodsId());
            if(goods.getSaleLimit()!=-1 && goods.getSaleDone() >= goods.getSaleLimit()){
                throw new RuntimeException("商品限购，数量不足");
            }

            //如果是限购商品，修改可购买商品数量
            if (goodsService.reduceLimit(productId, checkGoods.getNumber()) == 0) {
                throw new RuntimeException("商品可购买数量修改失败");
            }*/
        }

        // 如果使用了优惠券，设置优惠券使用状态
        if (couponId != 0 && couponId != -1) {
            NearbyshopCouponUser couponUser = couponUserService.queryOne(userId, couponId);
            couponUser.setStatus(CouponUserConstant.STATUS_USED);
            couponUser.setUsedTime(LocalDateTime.now());
            couponUser.setOrderId(couponOrderId);
            couponUserService.update(couponUser);
        }

        //如果是团购项目，添加团购信息
        if (grouponRulesId != null && grouponRulesId > 0) {
            NearbyshopGroupon groupon = new NearbyshopGroupon();
            groupon.setOrderId(groupOrderId);
            groupon.setPayed(false);
            groupon.setUserId(userId);
            groupon.setRulesId(grouponRulesId);

            //参与者
            if (grouponLinkId != null && grouponLinkId > 0) {
                //参与的团购记录
                NearbyshopGroupon baseGroupon = grouponService.queryById(grouponLinkId);
                groupon.setCreatorUserId(baseGroupon.getCreatorUserId());
                groupon.setGrouponId(grouponLinkId);
                groupon.setShareUrl(baseGroupon.getShareUrl());
            } else {
                groupon.setCreatorUserId(userId);
                groupon.setGrouponId(0);
            }

            grouponService.createGroupon(groupon);
        }
        orderIds = (orderIds.substring(0,orderIds.length()-1));
        NearbyshopOrder comOrder = new NearbyshopOrder();
        comOrder.setUserId(userId);
        comOrder.setCorgOrderSn(orderIds);
        comOrder.setMercNo(mercNo);
        comOrder.setOrderSn(comOrderSn);
        comOrder.setOrderStatus(OrderUtil.STATUS_CREATE);
        comOrder.setConsignee(consignee);
        comOrder.setMobile(mobile);
        comOrder.setMessage(message);
        comOrder.setAddress(detailedAddress);
        comOrder.setGoodsPrice(totalGoodsPrice);
        comOrder.setFreightPrice(totalFreightPrice);
        comOrder.setCouponPrice(totalCouponPrice);
        comOrder.setIntegralPrice(totalIntegralPrice);
        //BigDecimal orderTotalPrice = infoVo.getCheckedGoodsPrice().add(freightPrice).subtract(infoVo.getCouponPrice());
        comOrder.setOrderPrice(totalOrderPrice);
        //BigDecimal actualPrice = orderTotalPrice.subtract(integralPrice);
        comOrder.setActualPrice(totalActPrice);
        comOrder.setGrouponPrice(totalGrouponPrice);
        comOrder.setYouhuiPrice(totalYouhuiPrice);
        comOrder.setBuchaPrice(totalBuchaPrice);
        comOrder.setDeleted(false);
/*        // 有团购活动
        if (grouponRules != null) {
            comOrder.setGrouponPrice(infoVo.getGrouponPrice());    //  团购价格
        } else {
            comOrder.setGrouponPrice(new BigDecimal(0.00));    //  团购价格
        }*/

        // 添加订单表项
        orderService.add(comOrder);


        Map<String, Object> data = new HashMap<>();
//        data.put("orderId", (orderIds.substring(0,orderIds.length()-1)));
        data.put("orderId", comOrder.getId());
        return ResponseUtil.ok(data);
    }

    /**
     * 取消订单
     * <p>
     * 1. 检测当前订单是否能够取消；
     * 2. 设置订单取消状态；
     * 3. 商品货品库存恢复；
     * 4. TODO 优惠券；
     * 5. TODO 团购活动。
     *
     * @param userId 用户ID
     * @param body   订单信息，{ orderId：xxx }
     * @return 取消订单操作结果
     */
    @Transactional
    public Object cancel(Integer userId, String body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (orderId == null) {
            return ResponseUtil.badArgument();
        }

        NearbyshopOrder order = orderService.findById(orderId);
        if (order == null) {
            return ResponseUtil.badArgumentValue();
        }
        if (!order.getUserId().equals(userId)) {
            return ResponseUtil.badArgumentValue();
        }

        LocalDateTime preUpdateTime = order.getUpdateTime();

        // 检测是否能够取消
        OrderHandleOption handleOption = OrderUtil.build(order);
        if (!handleOption.isCancel()) {
            return ResponseUtil.fail(WxResponseCode.ORDER_INVALID_OPERATION, "订单不能取消");
        }

        // 设置订单已取消状态
        order.setOrderStatus(OrderUtil.STATUS_CANCEL);
        order.setEndTime(LocalDateTime.now());
        if (orderService.updateWithOptimisticLocker(order) == 0) {
            throw new RuntimeException("更新数据已失效");
        }

        // 商品货品数量增加
        List<NearbyshopOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
        for (NearbyshopOrderGoods orderGoods : orderGoodsList) {
            Integer productId = orderGoods.getProductId();
            Short number = orderGoods.getNumber();
            if (productService.addStock(productId, number) == 0) {
                throw new RuntimeException("商品货品库存增加失败");
            }
        }

        return ResponseUtil.ok();
    }

    /**
     * 付款订单的预支付会话标识
     * <p>
     * 1. 检测当前订单是否能够付款
     * 2. 微信商户平台返回支付订单ID
     * 3. 设置订单付款状态
     *
     * @param userId 用户ID
     * @param body   订单信息，{ orderId：xxx }
     * @return 支付订单ID
     */
    @Transactional
    public Object prepay(Integer userId, String body, HttpServletRequest request) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (orderId == null) {
            return ResponseUtil.badArgument();
        }

        NearbyshopOrder order = orderService.findById(orderId);
        if (order == null) {
            return ResponseUtil.badArgumentValue();
        }
        if (!order.getUserId().equals(userId)) {
            return ResponseUtil.badArgumentValue();
        }

        // 检测是否能够取消
        OrderHandleOption handleOption = OrderUtil.build(order);
        if (!handleOption.isPay()) {
            return ResponseUtil.fail(WxResponseCode.ORDER_INVALID_OPERATION, "订单不能支付");
        }

        NearbyshopUser user = userService.findById(userId);
        String openid = user.getWeixinOpenid();
        if (openid == null) {
            return ResponseUtil.fail(WxResponseCode.AUTH_OPENID_UNACCESS, "订单不能支付");
        }
        Map<String, String> result = null;
//        WxPayMpOrderResult payResult = null;
        try {
            //原生支付的
//            WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
//            orderRequest.setOutTradeNo(order.getOrderSn());
//            orderRequest.setOpenid(openid);
//            orderRequest.setBody("订单：" + order.getOrderSn());
//            // 元转成分
//            int fee = 0;
//            BigDecimal actualPrice = order.getActualPrice();
//            fee = actualPrice.multiply(new BigDecimal(100)).intValue();
//            orderRequest.setTotalFee(fee);
//            orderRequest.setSpbillCreateIp(IpUtil.getIpAddr(request));
//
//            payResult = wxPayService.createOrder(orderRequest);
            Map<String, String> context = new HashMap<>();
            context.put("openid", openid);
            context.put("txnAmt", order.getActualPrice().toPlainString());
            String tranId = orderService.generateOrderSn(userId);
            order.setOrderSn(tranId);
            context.put("tranId", order.getOrderSn());

            //是否是可分账商户，是可分账商户直接分账
            //这里暂不管分账，由返利模块计算展示
 /*           String mercNo = order.getMercNo();
            if (!StringUtils.isEmpty(mercNo)) {

                NearbyshopMerc merc = mercService.queryByMercNo(mercNo);
                if (!StringUtils.isEmpty(merc.getOrgNo())) {
                    //分账
                    JSONArray fenzhangList = new JSONArray();
                    Map<String, String> fenz = new HashMap<>();
                    fenz.put("mercNo", merc.getOrgNo());
                    List<NearbyshopOrderGoods> orderGoodsList = orderGoodsService.queryByOid(order.getId());
                    BigDecimal fenzAmount = BigDecimal.ZERO;
                    for (NearbyshopOrderGoods orderGoods:
                            orderGoodsList) {
                        fenzAmount = fenzAmount.add(orderGoods.getMercProfit());
                    }
                    fenz.put("amount", fenzAmount.setScale(2, BigDecimal.ROUND_DOWN).stripTrailingZeros().toPlainString());
//                    fenzhangList.add(fenz);
                    fenzhangList.put(fenz);
                    if (!StringUtils.isEmpty(merc.getReferMerc())) {
                        Map<String, String> fenzRefer = new HashMap<>();
                        fenzRefer.put("mercNo", merc.getReferMerc());
                        fenzRefer.put("amount", fenzAmount.multiply(SystemConfig.getMercReferPercent()).setScale(2, BigDecimal.ROUND_DOWN).stripTrailingZeros().toPlainString());
                        fenzhangList.put(fenzRefer);
                    }
                    context.put("fenZhangJsonStr", fenzhangList.toString());
                }
            }*/

            result = cnlPayService.inteGrationPay(context);
            if (!org.springframework.util.StringUtils.isEmpty(result.get("packageValue")))
            {
                String prepayId = (String)result.get("packageValue");
                prepayId = prepayId.replace("prepay_id=", "");
                NearbyshopUserFormid userFormid = new NearbyshopUserFormid();
                userFormid.setOpenid(user.getWeixinOpenid());
                userFormid.setFormid(prepayId);
                userFormid.setIsprepay(Boolean.valueOf(true));
                userFormid.setUseamount(Integer.valueOf(3));
                userFormid.setExpireTime(LocalDateTime.now().plusDays(7L));
                this.formIdService.addUserFormid(userFormid);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.fail(WxResponseCode.ORDER_PAY_FAIL, "订单不能支付");
        }

        logger.info("支付返回1：");
        if (orderService.updateWithOptimisticLocker(order) != 0) {
            logger.info("支付返回2：");
            String[] ids = order.getCorgOrderSn().split(",");
            for(String oid : ids){
                NearbyshopOrder2 update = new NearbyshopOrder2();
                update.setId(Integer.valueOf(oid));
                update.setPayOrderSn(order.getOrderSn());
                logger.info("支付返回3：" + oid + "-" + order.getOrderSn());
                orderService2.updateById(update);
            }
        }else {
            return ResponseUtil.updatedDateExpired();
        }
        logger.info("支付返回2：" + result);
        return ResponseUtil.ok(result);
    }

    /**
     * 付款订单的预支付会话标识
     * <p>
     * 1. 检测当前订单是否能够付款
     * 2. 微信商户平台返回支付订单ID
     * 3. 设置订单付款状态
     *
     * @param userId 用户ID
     * @param body   订单信息，{ orderId：xxx }
     * @return 支付订单ID
     */
    @Transactional
    public Object prepayNative(Integer userId, String body, HttpServletRequest request) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (orderId == null) {
            return ResponseUtil.badArgument();
        }

        NearbyshopOrder order = orderService.findById(orderId);
        if (order == null) {
            return ResponseUtil.badArgumentValue();
        }
        if (!order.getUserId().equals(userId)) {
            return ResponseUtil.badArgumentValue();
        }

        // 检测是否能够取消
        OrderHandleOption handleOption = OrderUtil.build(order);
        if (!handleOption.isPay()) {
            return ResponseUtil.fail(WxResponseCode.ORDER_INVALID_OPERATION, "订单不能支付");
        }

        NearbyshopUser user = userService.findById(userId);
        String openid = user.getWeixinOpenid();
        if (openid == null) {
            return ResponseUtil.fail(WxResponseCode.AUTH_OPENID_UNACCESS, "订单不能支付");
        }
        Map<String, String> result = null;
        WxPayMpOrderResult payResult = null;
        try {
            //原生支付的
            WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
            orderRequest.setOutTradeNo(order.getOrderSn());
            orderRequest.setOpenid(openid);
            orderRequest.setBody("订单：" + order.getOrderSn());
            // 元转成分
            int fee = 0;
            BigDecimal actualPrice = order.getActualPrice();
            fee = actualPrice.multiply(new BigDecimal(100)).intValue();
            orderRequest.setTotalFee(fee);
            orderRequest.setSpbillCreateIp(IpUtil.getIpAddr(request));

            payResult = wxPayService.createOrder(orderRequest);
//            Map<String, String> context = new HashMap<>();
//            context.put("openid", openid);
//            context.put("txnAmt", order.getActualPrice().toPlainString());
//            String tranId = orderService.generateOrderSn(userId);
//            order.setOrderSn(tranId);
//            context.put("tranId", order.getOrderSn());
//
//            //是否是可分账商户，是可分账商户直接分账
//            String mercNo = order.getMercNo();
//            if (!StringUtils.isEmpty(mercNo)) {
//
//                NearbyshopMerc merc = mercService.queryByMercNo(mercNo);
//                if (!StringUtils.isEmpty(merc.getOrgNo())) {
//                    //分账
//                    JSONArray fenzhangList = new JSONArray();
//                    Map<String, String> fenz = new HashMap<>();
//                    fenz.put("mercNo", merc.getOrgNo());
//                    List<NearbyshopOrderGoods> orderGoodsList = orderGoodsService.queryByOid(order.getId());
//                    BigDecimal fenzAmount = BigDecimal.ZERO;
//                    for (NearbyshopOrderGoods orderGoods:
//                            orderGoodsList) {
//                        fenzAmount = fenzAmount.add(orderGoods.getMercProfit());
//                    }
//                    fenz.put("amount", fenzAmount.setScale(2, BigDecimal.ROUND_DOWN).stripTrailingZeros().toPlainString());
////                    fenzhangList.add(fenz);
//                    fenzhangList.put(fenz);
//                    if (!StringUtils.isEmpty(merc.getReferMerc())) {
//                        Map<String, String> fenzRefer = new HashMap<>();
//                        fenzRefer.put("mercNo", merc.getReferMerc());
//                        fenzRefer.put("amount", fenzAmount.multiply(SystemConfig.getMercReferPercent()).setScale(2, BigDecimal.ROUND_DOWN).stripTrailingZeros().toPlainString());
//                        fenzhangList.put(fenzRefer);
//                    }
//                    context.put("fenZhangJsonStr", fenzhangList.toString());
//                }
//            }
//
//            result = cnlPayService.inteGrationPay(context);
            if (!StringUtils.isEmpty(payResult.getPackageValue())) {
                //缓存prepayID用于后续模版通知
                String prepayId = payResult.getPackageValue();
                prepayId = prepayId.replace("prepay_id=", "");
                NearbyshopUserFormid userFormid = new NearbyshopUserFormid();
                userFormid.setOpenid(user.getWeixinOpenid());
                userFormid.setFormid(prepayId);
                userFormid.setIsprepay(true);
                userFormid.setUseamount(3);
                userFormid.setExpireTime(LocalDateTime.now().plusDays(7));
                formIdService.addUserFormid(userFormid);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.fail(WxResponseCode.ORDER_PAY_FAIL, "订单不能支付");
        }

        if (orderService.updateWithOptimisticLocker(order) == 0) {
            return ResponseUtil.updatedDateExpired();
        }
        return ResponseUtil.ok(payResult);
    }

    /**
     * 微信付款成功或失败回调接口
     * <p>
     * 1. 检测当前订单是否是付款状态;
     * 2. 设置订单付款成功状态相关信息;
     * 3. 响应微信商户平台.
     *
     * @param request  请求内容
     * @param response 响应内容
     * @return 操作结果
     */
    @Transactional
    public Object payNotify(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> param = new HashMap<>();
        Enumeration<?> enu = null;
        try {
            enu = request.getParameterNames();
        } catch (Exception e) {
            e.printStackTrace();
        }
        while (enu.hasMoreElements()) {
            String paraName = (String) enu.nextElement();
            param.put(paraName, request.getParameter(paraName));
        }

        logger.info("处理第三方支付平台的订单支付");
        logger.info(param);

        String orderSn = param.get("outTransNo");
        String payId = param.get("transactionId");
        String corgOrderSn = param.get("transNo");

        // 分转化成元
        String totalFee = param.get("amount");
        NearbyshopOrder orderCom = orderService.findBySn(orderSn);
        if (orderCom == null) {
            return WxPayNotifyResponse.fail("订单不存在 sn=" + orderSn);
        }

        // 检查这个订单是否已经处理过
        if (OrderUtil.isPayStatus(orderCom) && orderCom.getPayId() != null) {
//            return WxPayNotifyResponse.success("订单已经处理成功!");
            return "success";
        }

        if (OrderUtil.isRefundConfirmStatus(orderCom) || OrderUtil.isRefundStatus(orderCom)) {
//            return WxPayNotifyResponse.success("订单已经处理成功!");
            return "success";
        }

        // 检查支付订单金额
        if (new BigDecimal(totalFee).compareTo(orderCom.getActualPrice()) != 0) {
            return WxPayNotifyResponse.fail(orderCom.getOrderSn() + " : 支付金额不符合 totalFee=" + totalFee);
        }

        String[] ids = orderCom.getCorgOrderSn().split(",");
        orderCom.setPayId(payId);
        orderCom.setCorgOrderSn(corgOrderSn);
        orderCom.setPayTime(LocalDateTime.now());
        orderCom.setOrderStatus(OrderUtil.STATUS_PAY);
        orderCom.setDeleted(true);
        if (orderService.updateWithOptimisticLocker(orderCom) == 0) {
            // 这里可能存在这样一个问题，用户支付和系统自动取消订单发生在同时
            // 如果数据库首先因为系统自动取消订单而更新了订单状态；
            // 此时用户支付完成回调这里也要更新数据库，而由于乐观锁机制这里的更新会失败
            // 因此，这里会重新读取数据库检查状态是否是订单自动取消，如果是则更新成支付状态。
            orderCom = orderService.findBySn(orderSn);
            int updated = 0;
            if (OrderUtil.isAutoCancelStatus(orderCom)) {
                orderCom.setPayId(payId);
                orderCom.setPayTime(LocalDateTime.now());
                orderCom.setOrderStatus(OrderUtil.STATUS_PAY);
                updated = orderService.updateWithOptimisticLocker(orderCom);
            }

            // 如果updated是0，那么数据库更新失败
            if (updated == 0) {
                return WxPayNotifyResponse.fail("更新数据已失效");
            }
        }
        for(String oid : ids){
            NearbyshopOrder order = orderService.findById(Integer.valueOf(oid));
            order.setPayId(payId);
            order.setCorgOrderSn(corgOrderSn);
            order.setPayTime(LocalDateTime.now());
            order.setOrderStatus(OrderUtil.STATUS_PAY);
            order.setDeleted(false);
            if (orderService.updateWithOptimisticLocker(order) == 0) {
                // 这里可能存在这样一个问题，用户支付和系统自动取消订单发生在同时
                // 如果数据库首先因为系统自动取消订单而更新了订单状态；
                // 此时用户支付完成回调这里也要更新数据库，而由于乐观锁机制这里的更新会失败
                // 因此，这里会重新读取数据库检查状态是否是订单自动取消，如果是则更新成支付状态。
                order = orderService.findBySn(orderSn);
                int updated = 0;
                if (OrderUtil.isAutoCancelStatus(order)) {
                    order.setPayId(payId);
                    order.setPayTime(LocalDateTime.now());
                    order.setOrderStatus(OrderUtil.STATUS_PAY);
                    order.setDeleted(false);
                    updated = orderService.updateWithOptimisticLocker(order);
                }

                // 如果updated是0，那么数据库更新失败
                if (updated == 0) {
                    return WxPayNotifyResponse.fail("更新数据已失效");
                }
            }

            //  支付成功，有团购信息，更新团购信息
            NearbyshopGroupon groupon = grouponService.queryByOrderId(order.getId());
            if (groupon != null) {
                NearbyshopGrouponRules grouponRules = grouponRulesService.queryById(groupon.getRulesId());

                //仅当发起者才创建分享图片
                if (groupon.getGrouponId() == 0) {
                    String url = qCodeService.createGrouponShareImage(grouponRules.getGoodsName(), grouponRules.getPicUrl(), groupon,grouponRules);
                    groupon.setShareUrl(url);
                }
                groupon.setPayed(true);
                if (grouponService.updateById(groupon) == 0) {
                    return WxPayNotifyResponse.fail("更新数据已失效");
                }
            }
        }


        //TODO 发送邮件和短信通知，这里采用异步发送
        // 订单支付成功以后，会发送短信给用户，以及发送邮件给管理员
        //notifyService.notifyMail("新订单通知", order.toString());
        // 这里微信的短信平台对参数长度有限制，所以将订单号只截取后6位
        notifyService.notifySmsTemplateSync(orderCom.getMobile(), NotifyType.PAY_SUCCEED, new String[]{orderSn.substring(8, 14)});

        NearbyshopMerc mercInf = mercService.queryByMercNo(orderCom.getMercNo());
        // 请依据自己的模版消息配置更改参数
        String[] parms = new String[]{
                orderCom.getOrderSn(),
                orderCom.getOrderPrice().toString(),
                DateTimeUtil.getDateTimeDisplayString(orderCom.getAddTime()),
                orderCom.getConsignee(),
                orderCom.getMobile(),
                "扬途电商",
        };

        notifyService.notifyWxTemplate(userService.findById(orderCom.getUserId()).getWeixinOpenid(), NotifyType.PAY_SUCCEED, parms, "pages/index/index?orderId=" + orderCom.getId());

//        return WxPayNotifyResponse.success("处理成功!");
        return "success";
    }

    //@Transactional
    public Object payNotifyNative(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> param = new HashMap<>();
        try {
            StringBuffer result = new StringBuffer();
            BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            WeChatBuyPost postData = XmlHelper.parseXmlBean(result.toString(), WeChatBuyPost.class);
            if (!"SUCCESS".equals(postData.getReturn_code()) || StringUtils.isEmpty(postData.getOut_trade_no())) {
                throw new Exception("支付回调返回失败");
            }
            param = BeanUtil.bean2Map(postData);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }


        logger.info("处理第三方支付平台的订单支付");
        logger.info(param);

        String orderSn = param.get("out_trade_no").toString();
        String payId = param.get("transaction_id").toString();
//        String corgOrderSn = param.get("transNo").toString();

        // 分转化成元
        String totalFee = param.get("total_fee").toString();
        totalFee = BigDecimal.valueOf(Long.valueOf(totalFee)).divide(new BigDecimal(100)).toString();
        NearbyshopOrder orderCom = orderService.findBySn(orderSn);
        if (orderCom == null) {
            return WxPayNotifyResponse.fail("订单不存在 sn=" + orderSn);
        }

        // 检查这个订单是否已经处理过
        if (OrderUtil.isPayStatus(orderCom) && orderCom.getPayId() != null) {
//            return WxPayNotifyResponse.success("订单已经处理成功!");
            logger.info("订单已支付过");
            return "success";
        }

        if (OrderUtil.isRefundConfirmStatus(orderCom) || OrderUtil.isRefundStatus(orderCom)) {
//            return WxPayNotifyResponse.success("订单已经处理成功!");
            logger.info("订单已退款");
            return "success";
        }

        // 检查支付订单金额
        if (new BigDecimal(totalFee).compareTo(orderCom.getActualPrice()) != 0) {
            logger.info("订单金额不符:" + totalFee + "-" + orderCom.getActualPrice().toPlainString());
            return WxPayNotifyResponse.fail(orderCom.getOrderSn() + " : 支付金额不符合 totalFee=" + totalFee);
        }

        String[] ids = orderCom.getCorgOrderSn().split(",");
        orderCom.setPayId(payId);
//        orderCom.setCorgOrderSn(orderSn);
        orderCom.setPayTime(LocalDateTime.now());
        orderCom.setOrderStatus(OrderUtil.STATUS_PAY);
        orderCom.setDeleted(true);
        if (orderService.updateWithOptimisticLocker(orderCom) == 0) {
            // 这里可能存在这样一个问题，用户支付和系统自动取消订单发生在同时
            // 如果数据库首先因为系统自动取消订单而更新了订单状态；
            // 此时用户支付完成回调这里也要更新数据库，而由于乐观锁机制这里的更新会失败
            // 因此，这里会重新读取数据库检查状态是否是订单自动取消，如果是则更新成支付状态。
            orderCom = orderService.findBySn(orderSn);
            int updated = 0;
            if (OrderUtil.isAutoCancelStatus(orderCom)) {
                orderCom.setPayId(payId);
                orderCom.setPayTime(LocalDateTime.now());
                orderCom.setOrderStatus(OrderUtil.STATUS_PAY);
                updated = orderService.updateWithOptimisticLocker(orderCom);
            }

            // 如果updated是0，那么数据库更新失败
            if (updated == 0) {
                return WxPayNotifyResponse.fail("更新数据已失效");
            }
        }
        for(String oid : ids){
            NearbyshopOrder order = orderService.findById(Integer.valueOf(oid));
            order.setPayId(payId);
            //order.setCorgOrderSn(corgOrderSn);
            order.setPayTime(LocalDateTime.now());
            order.setOrderStatus(OrderUtil.STATUS_PAY);
            order.setDeleted(false);
            if (orderService.updateWithOptimisticLocker(order) == 0) {
                // 这里可能存在这样一个问题，用户支付和系统自动取消订单发生在同时
                // 如果数据库首先因为系统自动取消订单而更新了订单状态；
                // 此时用户支付完成回调这里也要更新数据库，而由于乐观锁机制这里的更新会失败
                // 因此，这里会重新读取数据库检查状态是否是订单自动取消，如果是则更新成支付状态。
                order = orderService.findBySn(orderSn);
                int updated = 0;
                if (OrderUtil.isAutoCancelStatus(order)) {
                    order.setPayId(payId);
                    order.setPayTime(LocalDateTime.now());
                    order.setOrderStatus(OrderUtil.STATUS_PAY);
                    order.setDeleted(false);
                    updated = orderService.updateWithOptimisticLocker(order);
                }

                // 如果updated是0，那么数据库更新失败
                if (updated == 0) {
                    return WxPayNotifyResponse.fail("更新数据已失效");
                }
            }

            //  支付成功，有团购信息，更新团购信息
            NearbyshopGroupon groupon = grouponService.queryByOrderId(order.getId());
            if (groupon != null) {
                NearbyshopGrouponRules grouponRules = grouponRulesService.queryById(groupon.getRulesId());

                //仅当发起者才创建分享图片
                if (groupon.getGrouponId() == 0) {
                    String url = qCodeService.createGrouponShareImage(grouponRules.getGoodsName(), grouponRules.getPicUrl(), groupon,grouponRules);
                    groupon.setShareUrl(url);
                }
                groupon.setPayed(true);
                if (grouponService.updateById(groupon) == 0) {
                    return WxPayNotifyResponse.fail("更新数据已失效");
                }
            }

            //TODO 发送邮件和短信通知，这里采用异步发送
            // 订单支付成功以后，会发送短信给用户，以及发送邮件给管理员
            NearbyshopAdmin admin = adminService.findById(order.getAdminId());
            if(!StringUtils.isEmpty(admin.getEmail())){
                String shotmsg = "【龙猫精选提醒您】您的店铺收到了一个新订单：收件人"+order.getConsignee()
                        +"；电话"+order.getMobile()+"；收件地址"+order.getAddress()+"，赶紧去处理吧！";
                notifyService.notifyMail("新订单通知", shotmsg,admin.getEmail());
            }


            // 这里微信的短信平台对参数长度有限制，所以将订单号只截取后6位
            notifyService.notifySmsTemplateSync(order.getMobile(), NotifyType.PAY_SUCCEED, new String[]{orderSn.substring(8, 14)});

            NearbyshopMerc mercInf = mercService.queryByMercNo(order.getMercNo());
            // 请依据自己的模版消息配置更改参数
            String[] parms = new String[]{
                    order.getOrderSn(),
                    order.getOrderPrice().toString(),
                    DateTimeUtil.getDateTimeDisplayString(order.getAddTime()),
                    order.getConsignee(),
                    order.getMobile(),
                    "扬途电商",
            };

            notifyService.notifyWxTemplate(userService.findById(order.getUserId()).getWeixinOpenid(), NotifyType.PAY_SUCCEED, parms, "pages/index/index?orderId=" + order.getId());
        }
        logger.info("订单更新成功");



//        return WxPayNotifyResponse.success("处理成功!");
        return "success";
    }

    /**
     * 订单申请退款
     * <p>
     * 1. 检测当前订单是否能够退款；
     * 2. 设置订单申请退款状态。
     *
     * @param userId 用户ID
     * @param body   订单信息，{ orderId：xxx }
     * @return 订单退款操作结果
     */
    @Transactional(rollbackFor = Exception.class)
    public Object refund(Integer userId, String body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (orderId == null) {
            return ResponseUtil.badArgument();
        }

        NearbyshopOrder order = orderService.findById(orderId);
        if (order == null) {
            return ResponseUtil.badArgument();
        }
        if (!order.getUserId().equals(userId)) {
            return ResponseUtil.badArgumentValue();
        }

        OrderHandleOption handleOption = OrderUtil.build(order);
        if (!handleOption.isRefund()) {
            return ResponseUtil.fail(WxResponseCode.ORDER_INVALID_OPERATION, "订单不能退款");
        }

        NearbyshopOrder2 order2 = orderService2.getById(orderId);
        NearbyshopOrderRefund refund = new NearbyshopOrderRefund();
        BeanUtils.copyProperties(order2,refund);
        refund.setOrderId(order2.getId());
        refund.setId(null);
        refund.setApplyTime(new Date());
        refund.setHandleTime(new Date());
        refund.setRefundStatus(1);
        refund.setRefundPrice(order2.getActualPrice());
        refund.setRefundReason("用户客户端申请退款");
        refund.setRefundBy("1");
        //多加入一个状态：已采购
        if(order.getOrderStatus().equals(OrderUtil.STATUS_PAY) && order.getPurchaseStatus().equals(1)){
            refund.setOrderStatus(OrderUtil.STATUS_PURCHASE.intValue());
        }
        //设置商品数量
        int gnum = 0;
        int i = 1;
        List<NearbyshopOrderGoods> goodsList = orderGoodsService.queryByOid(order.getId());
        for(NearbyshopOrderGoods og : goodsList){
            gnum += og.getNumber();
        }
        refund.setGoodsNum(gnum);
        refund.setAdminId(order2.getAdminId());
        refundService.save(refund);

        // 设置订单申请退款状态
        order.setOrderStatus(OrderUtil.STATUS_REFUND);
//        if (orderService.updateWithOptimisticLocker(order) == 0) {
//            return ResponseUtil.updatedDateExpired();
//        }

        //TODO 发送邮件和短信通知，这里采用异步发送
        // 有用户申请退款，邮件通知运营人员
        //notifyService.notifyMail("退款申请", order.toString());


        //新增方法，申请退款后直接退
        Map<String, String> context = new HashMap<>();
        context.put("tranId", order.getPayOrderSn());
        context.put("amount", order.getActualPrice().toPlainString());

        try {
            Map<String, String> result = cnlPayService.refundApply(context);
            if (!result.get(CMM_PARAM_RETURN_CODE).equals(SUC_RETURN_CODE)) {
                logger.warn("refund fail: " + result.get(CMM_PARAM_RETURN_MSG));
                return ResponseUtil.fail(WxResponseCode.ORDER_REFUND_FAILED, "订单退款失败");
            }
            order.setShipSn(result.get(UP_CORG_TRAN_ID));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

 /*       // 微信原生退款
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setOutTradeNo(order.getOrderSn());
        wxPayRefundRequest.setOutRefundNo("refund_" + order.getOrderSn());
        // 元转成分
        Integer totalFee = order.getActualPrice().multiply(new BigDecimal(100)).intValue();
        wxPayRefundRequest.setTotalFee(totalFee);
        wxPayRefundRequest.setRefundFee(totalFee);

        WxPayRefundResult wxPayRefundResult = null;
        try {
            wxPayRefundResult = wxPayService.refund(wxPayRefundRequest);
        } catch (WxPayException e) {
            e.printStackTrace();
            return ResponseUtil.fail( "订单退款失败");
        }
        if (!wxPayRefundResult.getReturnCode().equals("SUCCESS")) {
            logger.warn("refund fail: " + wxPayRefundResult.getReturnMsg());
            return ResponseUtil.fail( "订单退款失败");
        }
        */


        // 设置订单取消状态
        order.setOrderStatus(OrderUtil.STATUS_REFUND_CONFIRM);
        if (orderService.updateWithOptimisticLocker(order) == 0) {
            throw new RuntimeException("更新数据已失效");
        }

        // 商品货品数量增加
        List<NearbyshopOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
        for (NearbyshopOrderGoods orderGoods : orderGoodsList) {
            Integer productId = orderGoods.getProductId();
            Short number = orderGoods.getNumber();
            if (productService.addStock(productId, number) == 0) {
                throw new RuntimeException("商品货品库存增加失败");
            }
        }

        //TODO 发送邮件和短信通知，这里采用异步发送
        // 退款成功通知用户, 例如“您申请的订单退款 [ 单号:{1} ] 已成功，请耐心等待到账。”
        // 注意订单号只发后6位
        notifyService.notifySmsTemplate(order.getMobile(), NotifyType.REFUND, new String[]{order.getOrderSn().substring(8, 14)});

        return ResponseUtil.ok();
    }

    /**
     * 订单申请退款
     * <p>
     * 1. 检测当前订单是否能够退款；
     * 2. 设置订单申请退款状态。
     *
     * @param userId 用户ID
     * @param body   订单信息，{ orderId：xxx }
     * @return 订单退款操作结果
     */
    @Transactional(rollbackFor = Exception.class)
    public Object refundNative(Integer userId, String body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (orderId == null) {
            return ResponseUtil.badArgument();
        }

        NearbyshopOrder order = orderService.findById(orderId);
        if (order == null) {
            return ResponseUtil.fail("订单不存在");
        }
        if (!order.getUserId().equals(userId)) {
            return ResponseUtil.fail("订单不属于你");
        }

        OrderHandleOption handleOption = OrderUtil.build(order);
        if (!handleOption.isRefund()) {
            return ResponseUtil.fail(WxResponseCode.ORDER_INVALID_OPERATION, "订单不能退款");
        }

        NearbyshopOrder2 order2 = orderService2.getById(orderId);
        NearbyshopOrderRefund refund = new NearbyshopOrderRefund();
        BeanUtils.copyProperties(order2,refund);
        refund.setOrderId(order2.getId());
        refund.setId(null);
        refund.setApplyTime(new Date());
        refund.setHandleTime(new Date());
        refund.setRefundStatus(1);
        refund.setRefundPrice(order2.getActualPrice());
        refund.setRefundReason("用户客户端申请退款");
        refund.setRefundBy("1");
        //多加入一个状态：已采购
        if(order.getOrderStatus().equals(OrderUtil.STATUS_PAY) && order.getPurchaseStatus().equals(1)){
            refund.setOrderStatus(OrderUtil.STATUS_PURCHASE.intValue());
        }
        //设置商品数量
        int gnum = 0;
        int i = 1;
        List<NearbyshopOrderGoods> goodsList = orderGoodsService.queryByOid(order.getId());
        for(NearbyshopOrderGoods og : goodsList){
            gnum += og.getNumber();
        }
        refund.setGoodsNum(gnum);
        refundService.save(refund);

        // 设置订单申请退款状态
        order.setOrderStatus(OrderUtil.STATUS_REFUND);
//        if (orderService.updateWithOptimisticLocker(order) == 0) {
//            return ResponseUtil.updatedDateExpired();
//        }

        //TODO 发送邮件和短信通知，这里采用异步发送
        // 有用户申请退款，邮件通知运营人员
        //notifyService.notifyMail("退款申请", order.toString());


        //新增方法，申请退款后直接退
        /*Map<String, String> context = new HashMap<>();
        context.put("tranId", order.getOrderSn());
        context.put("amount", order.getActualPrice().toPlainString());

        try {
            Map<String, String> result = cnlPayService.refundApply(context);
            if (!result.get(CMM_PARAM_RETURN_CODE).equals(SUC_RETURN_CODE)) {
                logger.warn("refund fail: " + result.get(CMM_PARAM_RETURN_MSG));
                return ResponseUtil.fail(WxResponseCode.ORDER_REFUND_FAILED, "订单退款失败");
            }
            order.setShipSn(result.get(UP_CORG_TRAN_ID));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
*/

        // 微信原生退款
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setOutTradeNo(order.getPayOrderSn());
        wxPayRefundRequest.setOutRefundNo("refund_" + order.getPayOrderSn()+order.getOrderSn());
        NearbyshopOrder comOrder = orderService.findBySn(order.getPayOrderSn());
        // 元转成分
        Integer totalFee = comOrder.getActualPrice().multiply(new BigDecimal(100)).intValue();
        logger.info("totalFee=" + totalFee);
        logger.info("order actFee=" + order.getActualPrice());
        Integer refundFee = order.getActualPrice().multiply(new BigDecimal(100)).intValue();
        wxPayRefundRequest.setTotalFee(totalFee);
        logger.info("refundFee=" + refundFee);
        wxPayRefundRequest.setRefundFee(refundFee);

        WxPayRefundResult wxPayRefundResult = null;
        try {
            wxPayRefundResult = wxPayService.refund(wxPayRefundRequest);
        } catch (WxPayException e) {
            e.printStackTrace();
            return ResponseUtil.fail( "订单退款失败");
        }
        if (!wxPayRefundResult.getReturnCode().equals("SUCCESS")) {
            logger.warn("refund fail: " + wxPayRefundResult.getReturnMsg());
            return ResponseUtil.fail( "订单退款失败");
        }
        if (!wxPayRefundResult.getResultCode().equals("SUCCESS")) {
            logger.warn("refund fail: " + wxPayRefundResult.getReturnMsg());
            return ResponseUtil.fail( "订单退款失败");
        }


        // 设置订单取消状态
        order.setOrderStatus(OrderUtil.STATUS_REFUND_CONFIRM);
        if (orderService.updateWithOptimisticLocker(order) == 0) {
            throw new RuntimeException("更新数据已失效");
        }

        // 商品货品数量增加
        List<NearbyshopOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
        for (NearbyshopOrderGoods orderGoods : orderGoodsList) {
            Integer productId = orderGoods.getProductId();
            Short number = orderGoods.getNumber();
            if (productService.addStock(productId, number) == 0) {
                throw new RuntimeException("商品货品库存增加失败");
            }
        }

       /* comOrder.setActualPrice(comOrder.getActualPrice().subtract(order.getActualPrice()));
        orderService.updateWithOptimisticLocker(comOrder);*/
        //TODO 发送邮件和短信通知，这里采用异步发送
        // 退款成功通知用户, 例如“您申请的订单退款 [ 单号:{1} ] 已成功，请耐心等待到账。”
        // 注意订单号只发后6位
        notifyService.notifySmsTemplate(order.getMobile(), NotifyType.REFUND, new String[]{order.getOrderSn().substring(8, 14)});

        return ResponseUtil.ok();
    }

    /**
     * 确认收货
     * <p>
     * 1. 检测当前订单是否能够确认收货；
     * 2. 设置订单确认收货状态。
     *
     * @param userId 用户ID
     * @param body   订单信息，{ orderId：xxx }
     * @return 订单操作结果
     */
    public Object confirm(Integer userId, String body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (orderId == null) {
            return ResponseUtil.badArgument();
        }

        NearbyshopOrder order = orderService.findById(orderId);
        if (order == null) {
            return ResponseUtil.badArgument();
        }
        if (!order.getUserId().equals(userId)) {
            return ResponseUtil.badArgumentValue();
        }

        OrderHandleOption handleOption = OrderUtil.build(order);
        if (!handleOption.isConfirm()) {
            return ResponseUtil.fail(WxResponseCode.ORDER_INVALID_OPERATION, "订单不能确认收货");
        }

        Short comments = orderGoodsService.getComments(orderId);
        order.setComments(comments);

        order.setOrderStatus(OrderUtil.STATUS_CONFIRM);
        order.setConfirmTime(LocalDateTime.now());
        if (orderService.updateWithOptimisticLocker(order) == 0) {
            return ResponseUtil.updatedDateExpired();
        }

        //返利
        rebateService.addRebateData(order);
        return ResponseUtil.ok();
    }

    /**
     * 删除订单
     * <p>
     * 1. 检测当前订单是否可以删除；
     * 2. 删除订单。
     *
     * @param userId 用户ID
     * @param body   订单信息，{ orderId：xxx }
     * @return 订单操作结果
     */
    public Object delete(Integer userId, String body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (orderId == null) {
            return ResponseUtil.badArgument();
        }

        NearbyshopOrder order = orderService.findById(orderId);
        if (order == null) {
            return ResponseUtil.badArgument();
        }
        if (!order.getUserId().equals(userId)) {
            return ResponseUtil.badArgumentValue();
        }

        OrderHandleOption handleOption = OrderUtil.build(order);
        if (!handleOption.isDelete()) {
            return ResponseUtil.fail(WxResponseCode.ORDER_INVALID_OPERATION, "订单不能删除");
        }

        // 订单order_status没有字段用于标识删除
        // 而是存在专门的delete字段表示是否删除
        orderService.deleteById(orderId);

        return ResponseUtil.ok();
    }

    /**
     * 待评价订单商品信息
     *
     * @param userId  用户ID
     * @param orderId 订单ID
     * @param goodsId 商品ID
     * @return 待评价订单商品信息
     */
    public Object goods(Integer userId, Integer orderId, Integer goodsId) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        List<NearbyshopOrderGoods> orderGoodsList = orderGoodsService.findByOidAndGid(orderId, goodsId);
        int size = orderGoodsList.size();

        Assert.state(size < 2, "存在多个符合条件的订单商品");

        if (size == 0) {
            return ResponseUtil.badArgumentValue();
        }

        NearbyshopOrderGoods orderGoods = orderGoodsList.get(0);
        return ResponseUtil.ok(orderGoods);
    }

    /**
     * 评价订单商品
     * <p>
     * 确认商品收货或者系统自动确认商品收货后7天内可以评价，过期不能评价。
     *
     * @param userId 用户ID
     * @param body   订单信息，{ orderId：xxx }
     * @return 订单操作结果
     */
    public Object comment(Integer userId, String body) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }

        Integer orderGoodsId = JacksonUtil.parseInteger(body, "orderGoodsId");
        if (orderGoodsId == null) {
            return ResponseUtil.badArgument();
        }
        NearbyshopOrderGoods orderGoods = orderGoodsService.findById(orderGoodsId);
        if (orderGoods == null) {
            return ResponseUtil.badArgumentValue();
        }
        Integer orderId = orderGoods.getOrderId();
        NearbyshopOrder order = orderService.findById(orderId);
        if (order == null) {
            return ResponseUtil.badArgumentValue();
        }
        Short orderStatus = order.getOrderStatus();
        if (!OrderUtil.isConfirmStatus(order) && !OrderUtil.isAutoConfirmStatus(order)) {
            return ResponseUtil.fail(WxResponseCode.ORDER_INVALID_OPERATION, "当前商品不能评价");
        }
        if (!order.getUserId().equals(userId)) {
            return ResponseUtil.fail(WxResponseCode.ORDER_INVALID, "当前商品不属于用户");
        }
        Integer commentId = orderGoods.getComment();
        if (commentId == -1) {
            return ResponseUtil.fail(WxResponseCode.ORDER_COMMENT_EXPIRED, "当前商品评价时间已经过期");
        }
        if (commentId != 0) {
            return ResponseUtil.fail(WxResponseCode.ORDER_COMMENTED, "订单商品已评价");
        }

        String content = JacksonUtil.parseString(body, "content");
        Integer star = JacksonUtil.parseInteger(body, "star");
        if (star == null || star < 0 || star > 5) {
            return ResponseUtil.badArgumentValue();
        }
        Boolean hasPicture = JacksonUtil.parseBoolean(body, "hasPicture");
        List<String> picUrls = JacksonUtil.parseStringList(body, "picUrls");
        if (hasPicture == null || !hasPicture) {
            picUrls = new ArrayList<>(0);
        }

        // 1. 创建评价
        NearbyshopComment comment = new NearbyshopComment();
        comment.setUserId(userId);
        comment.setType((byte) 0);
        comment.setValueId(orderGoods.getGoodsId());
        comment.setStar(star.shortValue());
        comment.setContent(content);
        comment.setHasPicture(hasPicture);
        comment.setPicUrls(picUrls.toArray(new String[]{}));
        commentService.save(comment);

        // 2. 更新订单商品的评价列表
        orderGoods.setComment(comment.getId());
        orderGoodsService.updateById(orderGoods);

        // 3. 更新订单中未评价的订单商品可评价数量
        Short commentCount = order.getComments();
        if (commentCount > 0) {
            commentCount--;
        }
        order.setComments(commentCount);
        orderService.updateWithOptimisticLocker(order);

        return ResponseUtil.ok();
    }

    /**
     * 获取已购买此商品用户详情
     *
     * @param goodsId  商品ID
     * @param page 页编号
     * @param size 每页商品数量
     * @return 待评价订单商品信息
     */
    public Object getSaleUserList(Integer goodsId, Integer page, Integer size) {
        List<Map<String, Object>> saleInfoList = new ArrayList<>();
        Map<String, Object> salePeopleInfo;
        List<NearbyshopOrderGoods> orderGoodsList= orderGoodsService.queryByGid(goodsId, page, size, "add_time", "desc");
        for (NearbyshopOrderGoods orderGoods:orderGoodsList) {
            salePeopleInfo = new HashMap<>();
            NearbyshopUser user = userService.findById(orderService.findById(orderGoods.getOrderId()).getUserId());
            String nickName ="";
            if (!com.mysql.jdbc.StringUtils.isNullOrEmpty(user.getNickname())) {
                nickName = new String(Base64.getDecoder().decode(user.getNickname()));
            }
            salePeopleInfo.put("nickNm", nickName);
            salePeopleInfo.put("avatarUrl", user.getAvatar());
            salePeopleInfo.put("saleTm", orderGoods.getAddTime());
            salePeopleInfo.put("saleNum", orderGoods.getNumber());
            saleInfoList.add(salePeopleInfo);
        }
        return ResponseUtil.ok(saleInfoList);
    }

    public static BigDecimal calcBucha(double fromLon,double fromLat,double toLon,double toLat){
        BigDecimal bucha = new BigDecimal("0.0");
        double miles = GeoUtils.D_jw(fromLat,fromLon,toLat,toLon);
        if(miles>1000 && miles< 1500){
            bucha = bucha.add(new BigDecimal("2"));
        }else if(miles>=1500 ) {
            bucha = new BigDecimal(miles/500).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros();
        }else {
            bucha = new BigDecimal("0.0");
        }
        return bucha;
    }

}
